Skip to content

K8SPG-851 introduce persistent logs#1675

Open
gkech wants to merge 7 commits into
mainfrom
K8SPG-851
Open

K8SPG-851 introduce persistent logs#1675
gkech wants to merge 7 commits into
mainfrom
K8SPG-851

Conversation

@gkech

@gkech gkech commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

CHANGE DESCRIPTION

Jira: https://perconadev.atlassian.net/browse/K8SPG-851
Helm PR: TBD


Problem:
Short explanation of the problem.

Cause:
Short explanation of the root cause of the issue if applicable.

Solution:

Screenshot 2026-07-21 at 12 54 30 PM

FluentBit example configuration used to s3 otel envelope logs to s3 compatible storage:

      configuration: |
        pipeline:
          filters:
            - name: record_modifier
              match: "*"
              record:
                - e2e_marker present
          outputs:
            - name: s3
              match: "*.postgres"
              bucket: operator-testing
              endpoint: https://minio-service:9000
              tls: on
              tls.ca_file: /etc/fluentbit/tls/ca.crt
              region: us-east-1
              store_dir: /tmp/fluent-bit/s3
              total_file_size: 1M
              upload_timeout: 15s
              use_put_object: on
              s3_key_format: /$TAG/%Y/%m/%d/%H-%M-%S-$UUID
              s3_key_format_tag_delimiters: .
              processors:
                logs:
                  - name: opentelemetry_envelope

result in logs in minio(s3 compatible):

Screenshot 2026-07-24 at 4 53 47 PM
{"date":"2026-07-24T13:38:49.749953Z","__internal__":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:38:46.726 UTC [164] LOG:  starting PostgreSQL 18.4 - Percona Server for PostgreSQL 18.4.2 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 14.2.1 20250110 (Red Hat 14.2.1-13), 64-bit","e2e_marker":"present"}

more logs:

{"date":"2026-07-24T13:45:27.880092Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:45:27.879 UTC [189] LOG: statement: SELECT name, setting, unit, vartype, context, sourcefile FROM pg_catalog.pg_settings WHERE pg_catalog.lower(name) = ANY(ARRAY['archive_cleanup_command','primary_conninfo','primary_slot_name','promote_trigger_file','recovery_end_command','recovery_min_apply_delay','recovery_target','recovery_target_lsn','recovery_target_name','recovery_target_time','recovery_target_timeline','recovery_target_xid','restore_command'])","e2e_marker":"present"}
{"date":"2026-07-24T13:45:32.036233Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:45:32.035 UTC [198] LOG: statement: SELECT pg_catalog.pg_postmaster_start_time(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE ('x' || pg_catalog.substr(pg_catalog.pg_walfile_name(pg_catalog.pg_current_wal_lsn()), 1, 8))::bit(32)::int END, CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_flush_lsn(), '0/0')::bigint END, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_replay_lsn(), '0/0')::bigint, pg_catalog.pg_wal_lsn_diff(COALESCE(pg_catalog.pg_last_wal_receive_lsn(), '0/0'), '0/0')::bigint, pg_catalog.pg_is_in_recovery() AND pg_catalog.pg_is_wal_replay_paused(), pg_catalog.pg_last_xact_replay_timestamp(), pg_catalog.pg_wal_lsn_diff(wr.latest_end_lsn, '0/0')::bigint, wr.status, pg_catalog.current_setting('restore_command'), pg_catalog.pg_wal_lsn_diff(wr.written_lsn, '0/0')::bigint, (SELECT pg_catalog.array_to_json(pg_catalog.array_agg(pg_catalog.row_to_json(ri))) FROM (SELECT (SELECT rolname FROM pg_catalog.pg_authid WHERE oid = usesysid) AS usename, application_name, client_addr, w.state, sync_state, sync_priority FROM pg_catalog.pg_stat_get_wal_senders() w, pg_catalog.pg_stat_get_activity(pid)) AS ri) FROM pg_catalog.pg_stat_get_wal_receiver() AS wr","e2e_marker":"present"}
{"date":"2026-07-24T13:54:17.877003Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:17.876 UTC [189] LOG: statement: SELECT CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE ('x' || pg_catalog.substr(pg_catalog.pg_walfile_name(pg_catalog.pg_current_wal_lsn()), 1, 8))::bit(32)::int END, CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_flush_lsn(), '0/0')::bigint END, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_replay_lsn(), '0/0')::bigint, pg_catalog.pg_wal_lsn_diff(COALESCE(pg_catalog.pg_last_wal_receive_lsn(), '0/0'), '0/0')::bigint, pg_catalog.pg_is_in_recovery() AND pg_catalog.pg_is_wal_replay_paused(), 0, CASE WHEN latest_end_lsn IS NULL THEN NULL ELSE received_tli END, pg_catalog.pg_wal_lsn_diff(written_lsn, '0/0')::bigint, slot_name, conninfo, status, pg_catalog.current_setting('restore_command'), (SELECT pg_catalog.json_agg(s.) FROM (SELECT slot_name, slot_type as type, datoid::bigint, plugin, catalog_xmin, pg_catalog.pg_wal_lsn_diff(confirmed_flush_lsn, '0/0')::bigint AS confirmed_flush_lsn, pg_catalog.pg_wal_lsn_diff(restart_lsn, '0/0')::bigint AS restart_lsn, xmin FROM pg_catalog.pg_get_replication_slots() WHERE NOT failover) AS s), 'on', '', NULL FROM pg_catalog.pg_stat_get_wal_receiver()","e2e_marker":"present"}
{"date":"2026-07-24T13:54:17.877748Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:17.877 UTC [189] LOG: statement: SELECT name, setting, unit, vartype, context, sourcefile FROM pg_catalog.pg_settings WHERE pg_catalog.lower(name) = ANY(ARRAY['archive_cleanup_command','primary_conninfo','primary_slot_name','promote_trigger_file','recovery_end_command','recovery_min_apply_delay','recovery_target','recovery_target_lsn','recovery_target_name','recovery_target_time','recovery_target_timeline','recovery_target_xid','restore_command'])","e2e_marker":"present"}
{"date":"2026-07-24T13:54:22.041400Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:22.041 UTC [198] LOG: statement: SELECT pg_catalog.pg_postmaster_start_time(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE ('x' || pg_catalog.substr(pg_catalog.pg_walfile_name(pg_catalog.pg_current_wal_lsn()), 1, 8))::bit(32)::int END, CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_flush_lsn(), '0/0')::bigint END, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_replay_lsn(), '0/0')::bigint, pg_catalog.pg_wal_lsn_diff(COALESCE(pg_catalog.pg_last_wal_receive_lsn(), '0/0'), '0/0')::bigint, pg_catalog.pg_is_in_recovery() AND pg_catalog.pg_is_wal_replay_paused(), pg_catalog.pg_last_xact_replay_timestamp(), pg_catalog.pg_wal_lsn_diff(wr.latest_end_lsn, '0/0')::bigint, wr.status, pg_catalog.current_setting('restore_command'), pg_catalog.pg_wal_lsn_diff(wr.written_lsn, '0/0')::bigint, (SELECT pg_catalog.array_to_json(pg_catalog.array_agg(pg_catalog.row_to_json(ri))) FROM (SELECT (SELECT rolname FROM pg_catalog.pg_authid WHERE oid = usesysid) AS usename, application_name, client_addr, w.state, sync_state, sync_priority FROM pg_catalog.pg_stat_get_wal_senders() w, pg_catalog.pg_stat_get_activity(pid)) AS ri) FROM pg_catalog.pg_stat_get_wal_receiver() AS wr","e2e_marker":"present"}
{"date":"2026-07-24T13:54:27.876696Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:27.876 UTC [189] LOG: statement: SELECT CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE ('x' || pg_catalog.substr(pg_catalog.pg_walfile_name(pg_catalog.pg_current_wal_lsn()), 1, 8))::bit(32)::int END, CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_flush_lsn(), '0/0')::bigint END, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_replay_lsn(), '0/0')::bigint, pg_catalog.pg_wal_lsn_diff(COALESCE(pg_catalog.pg_last_wal_receive_lsn(), '0/0'), '0/0')::bigint, pg_catalog.pg_is_in_recovery() AND pg_catalog.pg_is_wal_replay_paused(), 0, CASE WHEN latest_end_lsn IS NULL THEN NULL ELSE received_tli END, pg_catalog.pg_wal_lsn_diff(written_lsn, '0/0')::bigint, slot_name, conninfo, status, pg_catalog.current_setting('restore_command'), (SELECT pg_catalog.json_agg(s.
) FROM (SELECT slot_name, slot_type as type, datoid::bigint, plugin, catalog_xmin, pg_catalog.pg_wal_lsn_diff(confirmed_flush_lsn, '0/0')::bigint AS confirmed_flush_lsn, pg_catalog.pg_wal_lsn_diff(restart_lsn, '0/0')::bigint AS restart_lsn, xmin FROM pg_catalog.pg_get_replication_slots() WHERE NOT failover) AS s), 'on', '', NULL FROM pg_catalog.pg_stat_get_wal_receiver()","e2e_marker":"present"}
{"date":"2026-07-24T13:54:27.877398Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:27.877 UTC [189] LOG: statement: SELECT name, setting, unit, vartype, context, sourcefile FROM pg_catalog.pg_settings WHERE pg_catalog.lower(name) = ANY(ARRAY['archive_cleanup_command','primary_conninfo','primary_slot_name','promote_trigger_file','recovery_end_command','recovery_min_apply_delay','recovery_target','recovery_target_lsn','recovery_target_name','recovery_target_time','recovery_target_timeline','recovery_target_xid','restore_command'])","e2e_marker":"present"}
{"date":"2026-07-24T13:54:32.040263Z","internal":{"group_attributes":{"resource":{},"scope":{}},"log_metadata":{}},"file":"/pgdata/pg18/log/postgresql-Fri.log","log":"2026-07-24 13:54:32.040 UTC [198] LOG: statement: SELECT pg_catalog.pg_postmaster_start_time(), CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE ('x' || pg_catalog.substr(pg_catalog.pg_walfile_name(pg_catalog.pg_current_wal_lsn()), 1, 8))::bit(32)::int END, CASE WHEN pg_catalog.pg_is_in_recovery() THEN 0 ELSE pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_current_wal_flush_lsn(), '0/0')::bigint END, pg_catalog.pg_wal_lsn_diff(pg_catalog.pg_last_wal_replay_lsn(), '0/0')::bigint, pg_catalog.pg_wal_lsn_diff(COALESCE(pg_catalog.pg_last_wal_receive_lsn(), '0/0'), '0/0')::bigint, pg_catalog.pg_is_in_recovery() AND pg_catalog.pg_is_wal_replay_paused(), pg_catalog.pg_last_xact_replay_timestamp(), pg_catalog.pg_wal_lsn_diff(wr.latest_end_lsn, '0/0')::bigint, wr.status, pg_catalog.current_setting('restore_command'), pg_catalog.pg_wal_lsn_diff(wr.written_lsn, '0/0')::bigint, (SELECT pg_catalog.array_to_json(pg_catalog.array_agg(pg_catalog.row_to_json(ri))) FROM (SELECT (SELECT rolname FROM pg_catalog.pg_authid WHERE oid = usesysid) AS usename, application_name, client_addr, w.state, sync_state, sync_priority FROM pg_catalog.pg_stat_get_wal_senders() w, pg_catalog.pg_stat_get_activity(pid)) AS ri) FROM pg_catalog.pg_stat_get_wal_receiver() AS wr","e2e_marker":"present"}

CHECKLIST

Jira

  • Is the Jira ticket created and referenced properly?
  • Does the Jira ticket have the proper statuses for documentation (Needs Doc) and QA (Needs QA)?
  • Does the Jira ticket link to the proper milestone (Fix Version field)?

Tests

  • Is an E2E test/test case added for the new feature/change?
  • Are unit tests added where appropriate?

Config/Logging/Testability

  • Are all needed new/changed options added to default YAML files?
  • Are all needed new/changed options added to the Helm Chart?
  • Did we add proper logging messages for operator actions?
  • Did we ensure compatibility with the previous version or cluster upgrade process?
  • Does the change support oldest and newest supported PG version?
  • Does the change support oldest and newest supported Kubernetes version?

Comment on lines +11 to +15
printf '%s %s\n' "$schedule" "$cmd" > /tmp/crontab
exec supercronic /tmp/crontab
else
exec go-cron "$schedule" sh -c "$cmd"
fi

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
printf '%s %s\n' "$schedule" "$cmd" > /tmp/crontab
exec supercronic /tmp/crontab
else
exec go-cron "$schedule" sh -c "$cmd"
fi
printf '%s %s\n' "$schedule" "$cmd" >/tmp/crontab
exec supercronic /tmp/crontab
else
exec go-cron "$schedule" sh -c "$cmd"
fi

"strings"
"time"

"github.com/percona/percona-postgresql-operator/v2/percona/logcollector"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector"

Comment thread deploy/cr.yaml
# - name: s3-ca
# secret:
# secretName: my-s3-ca
# logRotate:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gkech Can we use the same naming as in PSMDBO https://github.com/percona/percona-server-mongodb-operator/blob/main/deploy/cr.yaml
And also, please add the possibility of adding custom liveness/readyness probes for two new sidecars (we have added it for PSMDB as well).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes of course

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gkech, please update cr.yaml as well, and make sure we can add custom liveness/readiness probes (if we do not have a default one).

local logrotate_additional_conf_files=()
local conf_d_dir="/opt/crunchy/logcollector/logrotate/conf.d"

# Operator-managed postgres.conf overrides the default when present.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[shfmt] reported by reviewdog 🐶

Suggested change
# Operator-managed postgres.conf overrides the default when present.
# Operator-managed postgres.conf overrides the default when present.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new spec.logCollector feature to wire Fluent Bit + logrotate sidecars into PostgreSQL instance pods, including CRD/API updates, operator reconcile logic, container assets in the operator image, and E2E coverage.

Changes:

  • Add LogCollectorSpec / LogRotateSpec to the PerconaPGCluster API and regenerate deepcopy + CRD/bundle manifests.
  • Implement reconciliation to (a) inject log collector sidecars/volumes and (b) create/update/delete backing ConfigMaps.
  • Add build assets (entrypoint + fluent-bit/logrotate configs), default CR example, and a new KUTTL E2E test suite for log collection/rotation/S3 shipping.

Reviewed changes

Copilot reviewed 32 out of 38 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
pkg/apis/pgv2.percona.com/v2/zz_generated.deepcopy.go Adds deepcopy support for new log collector API types.
pkg/apis/pgv2.percona.com/v2/perconapgcluster_types.go Adds spec.logCollector API types and helper LogCollectorEnabled().
percona/logcollector/reconcile.go Implements sidecar/volume wiring and ConfigMap reconciliation for log collector.
percona/logcollector/reconcile_test.go Unit tests for reconcile behavior (ConfigMap lifecycle + sidecar wiring + version gate).
percona/logcollector/logrotate/container.go Builds the logrotate sidecar container spec.
percona/logcollector/container.go Builds fluent-bit + logrotate containers, volumes, and security context defaults.
percona/logcollector/container_test.go Unit tests for constructed containers/volumes.
percona/controller/pgcluster/controller.go Hooks logcollector reconciliation into main PGCluster reconcile flow.
internal/naming/names.go Removes unused PGBackRestRepoName constant.
e2e-tests/vars.sh Adds IMAGE_LOGCOLLECTOR test image variable.
e2e-tests/functions Wires IMAGE_LOGCOLLECTOR into generated CRs for tests.
e2e-tests/run-release.csv Enables logcollection scenario in release E2E runs.
e2e-tests/run-pr.csv Enables logcollection scenario in PR E2E runs.
e2e-tests/tests/logcollection/00-assert.yaml Asserts operator deployment/CRD presence for logcollection scenario.
e2e-tests/tests/logcollection/00-deploy-operator.yaml Deploys operator + client + MinIO prerequisites for logcollection scenario.
e2e-tests/tests/logcollection/01-assert.yaml Asserts cluster readiness and expected ConfigMaps.
e2e-tests/tests/logcollection/01-create-cluster.yaml Creates a cluster with logCollector enabled + custom fluent-bit/logrotate config and MinIO TLS wiring.
e2e-tests/tests/logcollection/02-assert.yaml Asserts backup success used to generate logs.
e2e-tests/tests/logcollection/02-generate-logs.yaml Generates Postgres and pgBackRest logs (SQL + on-demand backup).
e2e-tests/tests/logcollection/03-check-collected-logs.yaml Verifies sidecars exist and logs/config are actually being consumed.
e2e-tests/tests/logcollection/04-rotate-logs.yaml Forces logrotate run inside sidecar.
e2e-tests/tests/logcollection/05-check-rotated-logs.yaml Verifies rotated files exist on the data volume.
e2e-tests/tests/logcollection/06-check-s3-logs.yaml Verifies logs are shipped to MinIO (S3).
e2e-tests/tests/logcollection/99-remove-cluster-gracefully.yaml Cleanup step ensuring no finalizers/panics and operator teardown.
deploy/crd.yaml Updates CRD schema to include spec.logCollector.
deploy/bundle.yaml Updates bundle schema to include spec.logCollector.
deploy/cr.yaml Adds example/default logCollector configuration to sample CR.
build/postgres-operator/logcollector/logrotate/logrotate.conf Provides default logrotate rules for Postgres + pgBackRest logs.
build/postgres-operator/logcollector/fluentbit/parsers_multiline.conf Adds fluent-bit multiline parser configuration.
build/postgres-operator/logcollector/fluentbit/fluentbit.conf Top-level fluent-bit config with includes (including custom override dir).
build/postgres-operator/logcollector/fluentbit/fluentbit_pg.conf Fluent-bit inputs for Postgres and pgBackRest logs + stdout output.
build/postgres-operator/logcollector/fluentbit/custom/default.conf Placeholder custom config file in image layout.
build/postgres-operator/logcollector/entrypoint.sh Sidecar entrypoint: runs fluent-bit or scheduled logrotate with config validation.
build/postgres-operator/init-entrypoint.sh Copies logcollector assets into shared bin volume when present in operator image.
build/postgres-operator/Dockerfile Packages logcollector assets into the operator image at /logcollector.

Comment on lines +44 to +64
func securityContext(cr *v2.PerconaPGCluster) *corev1.SecurityContext {
if cr.Spec.LogCollector != nil && cr.Spec.LogCollector.ContainerSecurityContext != nil {
return cr.Spec.LogCollector.ContainerSecurityContext
}

sc := &corev1.SecurityContext{
RunAsNonRoot: new(true),
AllowPrivilegeEscalation: new(false),
Privileged: new(false),
Capabilities: &corev1.Capabilities{Drop: []corev1.Capability{"ALL"}},
SeccompProfile: &corev1.SeccompProfile{Type: corev1.SeccompProfileTypeRuntimeDefault},
}

// OpenShift assigns one shared UID to every container in the pod.
if cr.Spec.OpenShift == nil || !*cr.Spec.OpenShift {
sc.RunAsUser = new(postgresUserID)
sc.RunAsGroup = new(postgresUserID)
}

return sc
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not true, it was with values: https://go.dev/play/p/dTtSaU19JXe

Comment on lines +53 to +56
for i := range cr.Spec.InstanceSets {
cr.Spec.InstanceSets[i].Sidecars = append(cr.Spec.InstanceSets[i].Sidecars, containers...)
cr.Spec.InstanceSets[i].SidecarVolumes = append(cr.Spec.InstanceSets[i].SidecarVolumes, volumes...)
}
Path ${PG_LOG_DIR}/*.log,${PG_LOG_DIR}/*.csv
Tag ${POD_NAMESPACE}.${POD_NAME}.postgres
Refresh_Interval 5
DB /tmp/flb_pg.db

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we persist this across restarts?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gkech Do we need to add ignore_older option in this case? Who will remove this DB if it becomes big? What we will do in case of a major Fluentbit upgrade, which can require a DB update as well. Will we have a real advantage with the persist approach? If yes, we need to change it for all operators.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to add ignore_older option in this case?

Yes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who will remove this DB if it becomes big?

if we use ignore_older, the size of the db will be max the amount of days written there, and in general it will not grew thaaat big I guess

# extra time-based cap.
/pgdata/pg*/log/*.log
/pgdata/pg*/log/*.csv {
daily

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i wonder how this plays with postgresql's daily rotation according to weekday

ExtraConfig corev1.LocalObjectReference `json:"extraConfig,omitempty"`

// +optional
Schedule string `json:"schedule,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Default schedule can be added via kubebuilder tag

Comment on lines +907 to +911
// +optional
Configuration string `json:"configuration,omitempty"`

// +optional
ExtraConfig corev1.LocalObjectReference `json:"extraConfig,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to how we do for PSMDBO, we should add some description so the difference is clear

Suggested change
// +optional
Configuration string `json:"configuration,omitempty"`
// +optional
ExtraConfig corev1.LocalObjectReference `json:"extraConfig,omitempty"`
// Configuration allows overriding the default logrotate configuration.
// +optional
Configuration string `json:"configuration,omitempty"`
// ExtraConfig allows specifying logrotate configuration file in addition to the main configuration file.
// This should be a reference to a ConfigMap or a Secret in the same namespace.
// Key must contain the .conf extension to be processed correctly.
// +optional
ExtraConfig corev1.LocalObjectReference `json:"extraConfig,omitempty"`

Comment thread percona/logcollector/reconcile.go Outdated
return deleteConfigMapIfExists(ctx, c, cr.Namespace, name)
}

return createOrUpdateConfigMap(ctx, c, &corev1.ConfigMap{

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are not setting owner references on these ConfigMaps

Comment on lines +314 to +316
if err := logcollector.Reconcile(ctx, r.Client, cr); err != nil {
return reconcile.Result{}, errors.Wrap(err, "failed to reconcile log collector")
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not test it yet, but if the config is changed, will it take effect into the pods? In PSMDBO we include the logcollector config into the configuration-hash, so restart is triggered

Comment on lines +29 to +31
func postgresLogPath(cr *v2.PerconaPGCluster) string {
return fmt.Sprintf("/pgdata/pg%d/log", cr.Spec.PostgresVersion)
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the log directory be changed from dynamicConfiguration?

@mayankshah1607 mayankshah1607 Jul 24, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see there is a log_directory setting, I don't know if setting it is supported though

import (
"fmt"

"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"


"github.com/percona/percona-postgresql-operator/v2/internal/naming"
"github.com/percona/percona-postgresql-operator/v2/internal/postgres"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

import (
"testing"

"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"


"github.com/percona/percona-postgresql-operator/v2/internal/naming"
"github.com/percona/percona-postgresql-operator/v2/internal/postgres"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

"fmt"
"reflect"

"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

"github.com/percona/percona-postgresql-operator/v2/internal/naming"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"
pNaming "github.com/percona/percona-postgresql-operator/v2/percona/naming"

import (
"testing"

"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"

"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"

"github.com/percona/percona-postgresql-operator/v2/internal/naming"
"github.com/percona/percona-postgresql-operator/v2/percona/version"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[goimports-reviser] reported by reviewdog 🐶

Suggested change
"github.com/percona/percona-postgresql-operator/v2/percona/version"
"github.com/percona/percona-postgresql-operator/v2/percona/logcollector/logrotate"
"github.com/percona/percona-postgresql-operator/v2/percona/version"

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 34 out of 40 changed files in this pull request and generated 2 comments.

Comment thread deploy/cr.yaml
Comment on lines +742 to +747
# # Extra fluent-bit configuration merged with the operator-managed config.
# configuration: |
# [FILTER]
# Name record_modifier
# Match *
# Record cluster_name cluster1
Comment on lines +5 to +20
- script: |-
set -o errexit
set -o xtrace

source ../../functions

access_key="$(kubectl -n "${NAMESPACE}" get secret minio-secret -o jsonpath='{.data.AWS_ACCESS_KEY_ID}' | base64 -d)"
secret_key="$(kubectl -n "${NAMESPACE}" get secret minio-secret -o jsonpath='{.data.AWS_SECRET_ACCESS_KEY}' | base64 -d)"

check_s3_logs() {
kubectl -n "${NAMESPACE}" run -i --rm "aws-cli-${RANDOM}" \
--image=perconalab/awscli --restart=Never -- \
bash -c "AWS_ACCESS_KEY_ID='${access_key}' AWS_SECRET_ACCESS_KEY='${secret_key}' AWS_DEFAULT_REGION=us-east-1 \
/usr/bin/aws --endpoint-url https://minio-service:9000 --no-verify-ssl s3 ls s3://operator-testing/ --recursive" \
| grep -q postgres
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants